package DAO.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.persistence.Query;

import DAO.HibernateUtil;
import DAO.ScheduleDAO;
import DTO.DTOManager;
import DTO.ScheduleDTO;

import model.impl.Schedule;
import model.impl.Station;
import model.impl.Train;

public class ScheduleDAOImpl extends GenericDAOImpl<Schedule, Integer> implements
		ScheduleDAO {
	
	public List<ScheduleDTO> findRequiredTrains(Station beginStation,
			Station endStation, Date beginTime, Date endTime) {
		List<ScheduleDTO> schedulesDTO = null;
		try {
			HibernateUtil.beginTransaction();
			List<Schedule> schedules = null;
			String sqlRequest = "SELECT s FROM Schedule s WHERE s.station1 = :departure " +
					"AND s.station2 = :arrival AND s.dateOfDeparture BETWEEN :dateBegin AND :dateEnd";
			Query query = HibernateUtil.getSession().createQuery(sqlRequest).setParameter("departure", beginStation).
					setParameter("arrival", endStation).setParameter("dateBegin", beginTime).setParameter("dateEnd", endTime);
			schedules = this.findMany(query);
			if (schedules != null && !schedules.isEmpty()) {
				schedulesDTO = new ArrayList<ScheduleDTO>();
				for (int i = 0; i < schedules.size(); i++) {
					schedulesDTO.add(DTOManager.createScheduleDTO(schedules.get(i)));
				}
			}
			HibernateUtil.commitTransaction();
		} catch (Exception e) {
			HibernateUtil.rollbackTransaction();
            System.out.println("Error in findRequiredTrains");
            e.printStackTrace();
		}
		return schedulesDTO;
	}

	
	public Schedule findScheduleByScheduleDTO(ScheduleDTO scheduleDTO) {
		Schedule schedule = null;
		try {
			Train train = model.Train.trainDAO.findTrainByTrainNumber(scheduleDTO.getTrainNumber());
			Station station1 = model.Station.stationDAO.findStationByName(scheduleDTO.getStation1());
			Station station2 = model.Station.stationDAO.findStationByName(scheduleDTO.getStation2());
			HibernateUtil.beginTransaction();
			String sqlRequest = "SELECT s FROM Schedule s WHERE s.station1 = :departure " +
					"AND s.station2 = :arrival AND s.dateOfDeparture = :dateBegin AND s.dateOfArrival = :dateEnd AND s.train = :tr";
			Query query = HibernateUtil.getSession().createQuery(sqlRequest).setParameter("departure", station1).
					setParameter("arrival", station2).setParameter("dateEnd", scheduleDTO.getDateOfArrival()).setParameter("tr", train).
					setParameter("dateBegin", scheduleDTO.getDateOfDeparture());
			schedule = findOne(query);
			HibernateUtil.commitTransaction();
		}  catch (Exception e) {
			HibernateUtil.rollbackTransaction();
			e.printStackTrace();
            System.out.println("Error in findScheduleByScheduleDTO");
        }
		return schedule;
	}
	
	public Schedule findIsSchedulePossible(ScheduleDTO scheduleDTO) {
		Schedule schedule = null;
		try {
			Train train = model.Train.trainDAO.findTrainByTrainNumber(scheduleDTO.getTrainNumber());
			HibernateUtil.beginTransaction();
			String sqlRequest = "SELECT s FROM Schedule s WHERE (s.dateOfDeparture BETWEEN :dateBegin AND :dateEnd) OR (s.dateOfArrival BETWEEN :dateBegin AND :dateEnd)S AND s.train = :tr";
			Query query = HibernateUtil.getSession().createQuery(sqlRequest).setParameter("dateEnd", scheduleDTO.getDateOfArrival()).setParameter("tr", train).
					setParameter("dateBegin", scheduleDTO.getDateOfDeparture());
			schedule = findOne(query);
			HibernateUtil.commitTransaction();
		}  catch (Exception e) {
			HibernateUtil.rollbackTransaction();
			e.printStackTrace();
            System.out.println("Error in findScheduleByScheduleDTO");
        }
		return schedule;
	}
	

	public List<Schedule> findAllSchedulesByStation(Station station) {
		List<Schedule> schedules = null;
		try {
			HibernateUtil.beginTransaction();
			String sqlRequest = "SELECT s FROM Schedule s WHERE s.station1 = :station " +
					"OR s.station2 = :station";
			Query query = HibernateUtil.getSession().createQuery(sqlRequest).setParameter("station", station);
			schedules = findMany(query);
			HibernateUtil.commitTransaction();
		}  catch (Exception e) {
			HibernateUtil.rollbackTransaction();
			e.printStackTrace();
            System.out.println("Error in findAllSchedulesByStation");
        }
		return schedules;
	}
}
